#include <stdio.h>
#include <stdlib.h>

int a_count = 0;
int b_count = 0;
int c_count = 0;
int d_count = 0;

void __attribute__((noinline))
foo_a(int data[], int len)
{
   a_count++;
   int i, j, temp;
   for (j = 0; j < len - 1; j++)
   {
      for (i = 0; i < len - 1 - j; i++)
      {
         if (data[i] > data[i + 1])
         {
            temp = data[i];
            data[i] = data[i + 1];
            data[i + 1] = temp;
         }
      }
   }
}
void __attribute__((noinline))
foo_c(int data[], int len)
{
   c_count++;
   int i, j, temp;
   for (j = 0; j < len - 1; j++)
   {
      for (i = 0; i < len - 1 - j; i++)
      {
         if (data[i] < data[i + 1])
         {
            temp = data[i];
            data[i] = data[i + 1];
            data[i + 1] = temp;
         }
      }
   }
}

void __attribute__((noinline))
foo_d(int *a, int *b)
{
   d_count++;
   if (*a < *b)
   {
      int temp = *a;
      *a = *b;
      *b = temp;
   }
   else if (*a = *b)
   {
      *b = *b + 1;
   }
}

void __attribute__((noinline))
foo_b(int data[], int len)
{
   b_count++;
   int i, j, temp;
   for (j = 0; j < len - 1; j++)
   {
      for (i = 0; i < len - 1 - j; i++)
      {
         foo_d(&data[i], &data[i + 1]);
      }
   }
}

void __attribute__((noinline))
get_data(int data[], int len)
{
   FILE *fp = NULL;
   fp = fopen("data/test.txt", "rb");

   for (size_t i = 0; i < len; i++)
   {
      fread(&data[i], sizeof(int), 1, fp);
   }
   fclose(fp);
}

int main()
{
   int count = 1000;
   printf("run times: %d\n", count);

   int data[1000];
   int len = sizeof(data) / sizeof(int);

   get_data(data, 1000);

   int tmp = 0;
   while (count--)
   {
      foo_a(data, len);
      for (size_t i = 0; i < len; i++){
         if(data[i]<0){
            abort();
         }
      }
      tmp += data[100];

      foo_b(data, len);
      for (size_t i = 0; i < len; i++){
         if(data[i]<0){
            abort();
         }
      }
      tmp += data[100];

      foo_a(data, len);
      for (size_t i = 0; i < len; i++){
         if(data[i]<0){
            abort();
         }
      }
      tmp += data[100];

      foo_c(data, len);
      for (size_t i = 0; i < len; i++){
         if(data[i]<0){
            abort();
         }
      }
      tmp += data[100];
      
      tmp %= 100;
   }
   printf("result: %d\n", tmp);

   printf("call foo_a: %d\n", a_count);
   printf("call foo_b: %d\n", b_count);
   printf("call foo_c: %d\n", c_count);
   printf("call foo_d: %d\n", d_count);
   
   return 0;
}
// fwrite(&data, sizeof(int), 1, fp_a);
// fread(&data, sizeof(int), 1, fp_a);
